package cn.com.bluemoon.daps.sync.service.impl;

import cn.com.bluemoon.daps.common.exception.DapThrowException;
import cn.com.bluemoon.daps.sync.base.CompareResult;
import cn.com.bluemoon.daps.sync.base.ModifyType;
import cn.com.bluemoon.daps.sync.base.SqlCompareResult;
import cn.com.bluemoon.daps.sync.service.ModifySyncStatusHandler;
import cn.com.bluemoon.daps.sync.vo.applypublish.ModelCompareVo;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;

/**
 * @author Jarod.Kong
 */
@Slf4j
public abstract class AlterTableFieldModifySyncStatusBaseHandler implements ModifySyncStatusHandler {

    @Override
    public boolean canModStatus(ModelCompareVo compareVo) {
        if (CollUtil.isEmpty(compareVo.getFieldCompares())) {
            log.warn("对比修改字段为空，不可强制修改状态");
            return false;
        }
        try {
            boolean allMatchAlterTableField = compareVo.getFieldCompares().stream().allMatch(c -> ModifyType.ALTER.equals(c.getModifyType()));
            if (CollUtil.isEmpty(compareVo.getTableCompares()) &&
                    CollUtil.isEmpty(compareVo.getIndexCompares()) &&
                    CollUtil.isEmpty(compareVo.getPartitionCompares()) &&
                    allMatchAlterTableField
            ) {
                final String tableName = compareVo.getTableName();
                boolean matchForceUpdateStatus = compareVo.getFieldCompares().stream()
                        // allMatch所有sql都要满足syncStatusContext=true，每sql只要满足(anyMatch)其中一个handler为true即可
                        .allMatch(fieldCompare -> {
                            String sql = Optional.ofNullable(fieldCompare.getData()).map(d -> d.getScript()).map(s -> s.getSql()).orElse(null);
                            return matchAlterTableField(tableName, fieldCompare, sql);
                        });
                return matchForceUpdateStatus;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    protected SQLAlterTableStatement parseAlterStats(String sql, DbType dbType) {
        try {
            SQLStatement sqlStatement = SQLUtils.parseSingleStatement(sql, Optional.ofNullable(dbType).orElse(DbType.mysql));
            if (sqlStatement instanceof SQLAlterTableStatement) {
                SQLAlterTableStatement statement = (SQLAlterTableStatement) sqlStatement;
                return statement;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public abstract boolean matchAlterTableField(String tableName, CompareResult<SqlCompareResult> fieldCompare, String fieldAlterSql)throws DapThrowException;
}
